<?php
namespace Main;

include 'library/phpwebsocket/websocket.class.php';
include 'entity/player.php';
include 'entity/map.php';
include 'container/player.php';
include 'container/map.php';
include 'commandee.php';

class WsServer extends \WebSocket
{
    private $players    = NULL;
    private $maps       = NULL;
    private $commandee  = NULL;

    public function __construct($address, $port)
    {
        $this->setPlayerContainer(new \Container\Player());
        $this->setMapContainer(new \Container\Map());
        $this->commandee = new \Main\Commandee();

        parent::__construct($address, $port);
    }

    public function setPlayerContainer(\Container\Player $player_cont)
    {
        $this->players = $player_cont;
    }
    
    public function setMapContainer(\Container\Map $map_cont)
    {
        $this->maps = $map_cont;
    }
    
    public function process($user, $msg)
    {
        //$this->say('> '.$msg);
        $this->commandee->process($user, $msg, $this);
    }

    public function connect($socket)
    {
        // get the connected client's ip
        $client_ip = NULL;
        socket_getpeername($socket, $client_ip);
        // add player to container
        $this->players->addPlayer($client_ip, $socket);

        parent::connect($socket);
        $this->say('with ' . $client_ip);
    }

    public function disconnect($socket)
    {
        $id = $this->players->delPlayer($socket);
        
        // a player disconnected so send to all
        $this->sendToAll($socket, Commands::PLAYER_DISCONNECT.$this->commandee->setPlayer($id));
        
        $map_id = $this->maps->getMapByPlayerId($id);
        if ($map_id !== NULL)
        {
            $map_id = $map_id->getId();
            
            // the map's other player state goes to free and send him to a game over message
            $other_player = $this->maps->getMap($map_id)->getOtherPlayer($id);
            $this->players->getPlayer($other_player)->setState(\Entity\States::FREE);
            $this->sendToOne($this->players->getSocketById($other_player), Commands::GAME_OVER . Commandee::NO_ID);
            
            $this->maps->delMap($map_id);
        }

        parent::disconnect($socket);
    }
    
    public function getPlayers()
    {
        return $this->players;
    }
    
    public function getPlayer($id)
    {
        return $this->players->getPlayer($id);
    }
    
    public function getMaps()
    {
        return $this->maps;
    }

    public function getMap($id)
    {
        return $this->maps->getMap($id);
    }
    
    public function sendToOne($socket, $msg)
    {
        $this->send($socket, $msg);
    }

    public function sendToAll($except_socket, $msg)
    {
        foreach ($this->users as $user)
        {
            if ($user->socket === $except_socket) continue;

            $this->send($user->socket, $msg);
        }
    }
}

#eof
